﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace CardGameFramework
{
    public static class Extensions
    {
        public static Dictionary<Suits, string> SuitLabels = new Dictionary<Suits, string>()
        {
            {Suits.Clubs, "C"},
            {Suits.Diamonds, "D"},
            {Suits.Hearts, "H"},
            {Suits.Spades, "S"},
            {Suits.Joker, "J"}
        };

        public static Dictionary<Ranks, string> RankLabels = new Dictionary<Ranks, string>()
        {
            {Ranks.Two, "2"},
            {Ranks.Three, "3"},
            {Ranks.Four, "4"},
            {Ranks.Five, "5"},
            {Ranks.Six, "6"},
            {Ranks.Seven, "7"},
            {Ranks.Eight, "8"},
            {Ranks.Nine, "9"},
            {Ranks.Ten, "10"},
            {Ranks.Jack, "J"},
            {Ranks.Queen, "Q"},
            {Ranks.King, "K"},
            {Ranks.Ace, "A"},
            {Ranks.LittleJoker, "L"},
            {Ranks.BigJoker, "B"}
        };

        public static string GetLabel(this Suits suit)
        {
            return SuitLabels[suit];
        }

        public static string GetLabel(this Ranks rank)
        {
            return RankLabels[rank];
        }

        #region IEnumerable<T>
        /*
        /// <summary>
        /// Extends IEnumerable<T> to perform a specific Action against all members of the Sequence.
        /// </summary>
        /// <remarks>
        /// Richard Hale Shaw presented this method at VSLive! Austin 2007.
        /// </remarks>
        /// <code>
        /// </code>
        /// <typeparam name="T">Whatever Type is in the Sequence</typeparam>
        /// <param name="sequence">Extension Method Parameter:: this is an Extension reference to the actionable object.</param>
        /// <param name="action">The Action to perform on each item in the Sequence.</param>
         */
        public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
        {
            if (sequence == null)
            {
                throw new ArgumentNullException("sequence");
            }
            if (action == null)
            {
                throw new ArgumentNullException("action");
            }

            foreach (var item in sequence)
            {
                action(item);
            }
        }

        /*
        /// <summary>
        /// Extends IEnumerable<T> to return members of the sequence that match the requirements of the
        /// included Predicate<T>.
        /// </summary>
        /// <remarks>
        /// Richard Hale Shaw presented this method at VSLive! Austin 2007.
        /// </remarks>
        /// <typeparam name="T">Whatever Type is in the Sequence</typeparam>
        /// <param name="sequence">Extension Method Parameter:: this is an Extension reference to the actionable object.</param>
        /// <returns>An IEnumerable<T> in Iterator mode.</returns>
         */
        public static IEnumerable<T> Filter<T>(this IEnumerable<T> sequence, Predicate<T> predicate)
        {
            if (sequence == null)
            {
                throw new ArgumentNullException("sequence");
            }
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            }

            foreach (var item in sequence)
            {
                if (predicate(item))
                {
                    // Yield makes this perform like a Custom Iterator
                    // Returns control after each item
                    // Retains its position in the sequence
                    yield return item;
                }
            }
        }

        /*
        /// <summary>
        /// 
        /// </summary>
        /// <remarks>
        /// Richard Hale Shaw presented this method at VSLive! Austin 2007.
        /// </remarks>
        /// <typeparam name="T">Whatever Type is in the Sequence</typeparam>
        /// <param name="sequence">Extension Method Parameter:: this is an Extension reference to the actionable object.</param>
        /// <param name="comparison">Comparison<T> used to sort the sequence."/></param>
        /// <returns>An IEnumerable<T> in Iterator mode.</returns>
         */
        public static IEnumerable<T> Sort<T>(this IEnumerable<T> sequence, Comparison<T> comparison)
        {
            if (sequence == null)
            {
                throw new ArgumentNullException("sequence");
            }
            if (comparison == null)
            {
                throw new ArgumentNullException("comparison");
            }

            var list = new List<T>(sequence);
            list.Sort(comparison);
            foreach (var item in list)
            {
                // Yield makes this perform like a Custom Iterator
                // Returns control after each item
                // Retains its position in the sequence
                yield return item;
            }
        }
        #endregion

        #region IDictionary
        /// <summary>
        /// Executes the specified Action on all Value elements of the IDictionary.
        /// </summary>
        /// <typeparam name="K">The IDictionary Key Type.</typeparam>
        /// <typeparam name="V">The IDictionary Value Type.</typeparam>
        /// <param name="sequence">Extension Method Parameter:: this is an Extension reference to the actionable object.</param>
        /// <param name="action">The Action to perform on each Value in the IDictionary Sequence.</param>
        public static void ExecuteOnValues<K, V>(this IDictionary<K, V> sequence, Action<V> action)
        {
            Contract.Requires(sequence != null);
            Contract.Requires(action != null);

            if (sequence == null)
            {
                throw new ArgumentNullException("sequence");
            }

            foreach (var item in sequence.Values)
            {
                action(item);
            }
        }
        #endregion


    }
}